package com.ssy.lingxi.platform.manage.serviceimpl;

import cn.hutool.core.util.RandomUtil;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.platform.manage.api.model.dto.sensitive.*;
import com.ssy.lingxi.platform.manage.api.model.vo.sensitive.SensitiveWordFilterVO;
import com.ssy.lingxi.platform.manage.api.model.vo.sensitive.SensitiveWordListFilterVO;
import com.ssy.lingxi.platform.manage.entity.base.SensitiveWord;
import com.ssy.lingxi.platform.manage.repository.SensitiveWordRepository;
import com.ssy.lingxi.platform.manage.service.ISensitiveWordService;
import com.ssy.lingxi.platform.manage.util.SensitiveUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 敏感词 - 业务实现层
 * @author yzc
 * @version 2.0.0
 * @date 2020/10/27
 */
@Service
public class SensitiveWordServiceImpl implements ISensitiveWordService {

    @Resource
    private SensitiveWordRepository sensitiveWordRepository;

    /**
     * 平台后台-系统管理-敏感词管理-分页列表
     */
    @Override
    public Wrapper<PageData<SensitiveWord>> pageSensitiveWord(SensitiveWordPageDTO request) {
        Pageable page = PageRequest.of(request.getCurrent() - 1, request.getPageSize(), Sort.by("createTime").ascending());
        Page<SensitiveWord> all = sensitiveWordRepository.findAll((Specification<SensitiveWord>) (root, query, cb) -> {
            List<Predicate> predicateList = new ArrayList<>();
            if (Objects.nonNull(request.getName())) {
                predicateList.add(cb.like(root.get("name"), "%" + request.getName() + "%"));
            }
            return query.where(predicateList.toArray(new Predicate[predicateList.size()])).getRestriction();
        }, page);

        return Wrapper.success(new PageData<>(all.getTotalElements(), all.getContent()));
    }

    /**
     * 平台后台-系统管理-敏感词管理-添加
     */
    @Override
    public Wrapper<Void> addSensitiveWord(SensitiveWordDTO request) {
        Boolean flag = sensitiveWordRepository.existsByName(request.getName());
        if (flag) {
            return Wrapper.fail(ResponseCode.MAN_SENSITIVE_WORD_REPEAT);
        }

        // 批次号
        String batchNo = DateTimeFormatter.ofPattern("yyyyMMdd").format(LocalDate.now()) + RandomUtil.randomInt(1000);

        SensitiveWord sensitiveWord = new SensitiveWord();
        BeanUtils.copyProperties(request, sensitiveWord, "id");
        sensitiveWord.setBatchNo(batchNo);
        sensitiveWord.setCreateTime(System.currentTimeMillis());
        sensitiveWordRepository.saveAndFlush(sensitiveWord);

        // 重构关键词
        this.initSensitiveWord();

        return Wrapper.success();
    }

    /**
     * 平台后台-系统管理-敏感词管理-修改
     */
    @Override
    public Wrapper<Void> updateSensitiveWord(SensitiveWordDTO request) {
        Boolean flag = sensitiveWordRepository.existsByNameAndIdNot(request.getName(), request.getId());
        if (flag) {
            return Wrapper.fail(ResponseCode.MAN_SENSITIVE_WORD_REPEAT);
        }
        SensitiveWord sensitiveWord = sensitiveWordRepository.findById(request.getId()).orElse(null);
        if (Objects.isNull(sensitiveWord)) {
            return Wrapper.fail(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }

        sensitiveWord.setName(request.getName());
        sensitiveWord.setRemark(request.getRemark());
        sensitiveWordRepository.saveAndFlush(sensitiveWord);

        // 重构关键词
        this.initSensitiveWord();

        return Wrapper.success();
    }

    /**
     * 平台后台-系统管理-敏感词管理-删除
     */
    @Override
    public Wrapper<Void> deleteSensitiveWord(SensitiveWordDeleteByIdDTO request) {
        sensitiveWordRepository.deleteByIdIn(request.getIds());

        // 重构关键词
        this.initSensitiveWord();

        return Wrapper.success();
    }

    /**
     * 平台后台-系统管理-敏感词管理-批次删除
     */
    @Override
    public Wrapper<Void> deleteSensitiveWordByBatchNo(SensitiveWordDeleteByBatchNoDTO request) {
        sensitiveWordRepository.deleteByBatchNo(request.getBatchNo());

        // 重构关键词
        this.initSensitiveWord();

        return Wrapper.success();
    }

    /**
     * 内部接口-敏感词过滤
     */
    @Override
    public Wrapper<SensitiveWordFilterVO> filterSensitiveWord(SensitiveWordFilterDTO request) {
        if (Objects.isNull(request)) {
            return Wrapper.success(new SensitiveWordFilterVO());
        }

        // 敏感词过滤
        String content = SensitiveUtil.replace(request.getContent());

        SensitiveWordFilterVO response = new SensitiveWordFilterVO();
        response.setContent(content);
        return Wrapper.success(response);
    }

    /**
     * 内部接口-敏感词过滤(多个)
     */
    @Override
    public Wrapper<SensitiveWordListFilterVO> filterSensitiveWordList(SensitiveWordListFilterDTO request) {
        SensitiveWordListFilterVO response = new SensitiveWordListFilterVO();
        List<String> list = new ArrayList<>();
        if (CollectionUtils.isEmpty(request.getContents())) {
            response.setContents(list);
            return Wrapper.success(response);
        }

        for (String content : request.getContents()) {
            if (Objects.nonNull(content)) {
                String replace = SensitiveUtil.replace(content);
                list.add(replace);
            } else {
                list.add(content);
            }
        }

        response.setContents(list);
        return Wrapper.success(response);
    }

    @Override
    public void initSensitiveWord() {
        List<SensitiveWord> list = sensitiveWordRepository.findAll();
        List<String> wordList = list.stream().map(SensitiveWord::getName).collect(Collectors.toList());
        SensitiveUtil.init(wordList);
    }
}
